const http = require('http')
const https = require('https')
const url = require('url')
const { StringDecoder } = require('string_decoder')

const fs = require('fs')
// 将两个证书文件读取放到options对象中
// 使用readFileSync()方法，顺序地执行读文件和启动服务操作
const options = {
	key: fs.readFileSync('/etc/nginx/test.dotohi.com_nginx/test.dotohi.com.key'),
	cert: fs.readFileSync('/etc/nginx/test.dotohi.com_nginx/test.dotohi.com_bundle.crt'),
}

// HTTP 服务器 (80端口)
const httpServer = http.createServer((req, res) => {
	// 重定向所有HTTP请求到HTTPS
	res.writeHead(301, {
		Location: `https://${ req.headers.host }${ req.url }`,
	})
	res.end()
})

function getIpGeo(ip) {
	return new Promise((resolve, reject) => {
		const url = `http://ip-api.com/json/${ ip }?fields=country,regionName,city,isp,status,query,org,timezone,as`

		http.get(url, (res) => {
			let data = ''
			res.on('data', (chunk) => (data += chunk))
			res.on('end', () => {
				try {
					const entries = data
						.slice(1, -1)
						.split(',')
						.map((pair) => {
							const [key, value] = pair.split(':').map((s) => s.trim().replace(/"/g, ''))
							return [key, value]
						})

					const obj = Object.fromEntries(entries)

					if (obj.status === 'success') {
						resolve(obj)
					} else {
						reject(new Error(obj.message || 'IP 查询失败'))
					}
				} catch (err) {
					reject(err)
				}
			})
		}).on('error', reject)
	})
}

function print(data) {
	const blueBold = '\x1b[34;1m'
	const green = '\x1b[32m'
	const reset = '\x1b[0m' // 重置颜色

	for (const key in data) {
		console.log(`${ blueBold }${ key }:${ reset } ${ green }${ data[key] }${ reset }`)
	}
	console.log('-----------------------------------------------------------')
}

// 创建 HTTP 服务器
const httpsServer = https.createServer(options, async (req, res) => {
	// 设置CORS头
	res.setHeader('Access-Control-Allow-Origin', '*')
	res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
	res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')

	if (req.method === 'OPTIONS') {
		res.writeHead(200)
		res.end()
		return
	}

	if (req.url === '/favicon.ico') {
		res.writeHead(204) // No Content
		return res.end()
	}
	// 1. 解析请求路径和查询参数
	const parsedUrl = url.parse(req.url, true)
	const path = parsedUrl.pathname
	const query = parsedUrl.query

	// 2. 获取请求方法（GET/POST/PUT/DELETE/PATCH 等）
	const method = req.method.toUpperCase()

	// 3. 获取客户端 IP 和代理 IP（如果有）
	const clientIp = req.socket.remoteAddress || req.connection.remoteAddress
	const proxyIps = req.headers['x-forwarded-for'] // 代理服务器传递的原始 IP

	// 4. 模拟 IP 归属地查询（实际需接入第三方 API 或本地数据库）
	const ipGeolocation = await getIpGeolocation(clientIp.replace('::ffff:', ''))

	// 5. 获取请求头
	const headers = req.headers

	// 6. 处理请求体数据（非 GET 请求）
	let body = {}
	const decoder = new StringDecoder('utf-8')
	let rawBody = ''

	req.on('data', (chunk) => {
		rawBody += decoder.write(chunk)
	})

	req.on('end', () => {
		rawBody += decoder.end()

		// 尝试解析 JSON 或 Form-Data
		if (rawBody) {
			try {
				body = JSON.parse(rawBody)
			} catch (e) {
				// 如果不是 JSON，按 Form-Data 处理（简化版）
				body = rawBody.split('&').reduce((acc, pair) => {
					const [key, value] = pair.split('=')
					acc[key] = value
					return acc
				}, {})
			}
		}

		// 7. 构造响应数据
		const responseData = {
			clientIp: clientIp.replace('::ffff:', ''),
			proxyIps: proxyIps ? proxyIps.split(',') : null,
			ipGeolocation,
			method,
			path,
			query,
			headers,
			timestamp: new Date().toLocaleString('zh-CN'),
			body: Object.keys(body).length ? body : null,
		}

		print({
			...ipGeolocation,
			proxyIps: responseData['proxyIps'],
			method,
			timestamp: new Date().toLocaleString('zh-CN'),
			path,
			query: JSON.stringify(query),
			'user-agent': responseData['headers']['user-agent'] || '',
			body: JSON.stringify(responseData['body']),
		})

		// 8. 返回 JSON 响应
		res.setHeader('Content-Type', 'application/json')
		res.end(JSON.stringify(responseData, null, 2))
	})
})

// 模拟 IP 归属地查询（实际需替换为真实逻辑）
async function getIpGeolocation(ip) {
	// 示例：简单判断 IPv4/IPv6 和本地 IP
	if (ip === '::1' || ip === '127.0.0.1') {
		return { type: 'local', country: 'Localhost' }
	}

	try {
		const res = await getIpGeo(ip) // Google DNS
		delete res.status
		return { ip: res.query, ...res }
	} catch (err) {
		console.error('Error:', err.message)
	}
}

// 启动服务器
const PORT80 = 80
httpServer.listen(PORT80, () => {
	console.log(`Server running on port: ${ PORT80 }`)
	console.log('-----------------------------------------------------------')
})
const PORT443 = 443
httpsServer.listen(PORT443, () => {
	console.log(`Server running on port: ${ PORT443 }`)
	console.log('-----------------------------------------------------------')
})
